#include "mine_usart2.h"

#include "stdio.h"
#include "stdint.h"
#include "stdlib.h"
#include "stm32f4xx.h"
#include "stm32f4xx_usart.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_exti.h"
#include "misc.h"
#include "stdio.h"
#include "stdint.h"
#include "string.h"
#include "atkp.h"

#include "mine_remoter_ctrl.h"
#include "mine_fly_control.h"
/**
 * 与无线芯片通信,通过串口
 */
void mine_usart2_init(void)
{
    //
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); // PA3:TX PA2:RX PA0:CTRL

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
    // rx : 浮空
    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3;    // PA3 (TX)
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; // 复用模式
    // GPIO_InitStruct.GPIO_Speed = GPIO_Speed_25MHz;
    // GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;   // 推挽输出
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; // 无上拉
    GPIO_Init(GPIOA, &GPIO_InitStruct);

    // nrf的rx,对应自己的 tx:pa2
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2; //
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_25MHz;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
    // GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; // 浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStruct);

    // 配置PA2/PA3复用为USART2
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);

    // usart配置
    USART_InitTypeDef USART_InitStructure;
    USART_InitStructure.USART_BaudRate = 1000000;                   // 波特率1M
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // 发送 + 接收
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No; // 不校验
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_Init(USART2, &USART_InitStructure);
    //
    USART_Cmd(USART2, ENABLE); // 使能USART2

    // 中断
    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); // 接收中断
    // USART_ITConfig(USART2, USART_IT_TXE, ENABLE);  // 发送中断（可选）,加了这一行会导致printf()不能显示
    USART_ITConfig(USART2, USART_IT_IDLE, ENABLE); // 接收中断（可选）
    //
    NVIC_InitTypeDef NVIC_InitStruct;
    NVIC_InitStruct.NVIC_IRQChannel = USART2_IRQn;
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 7; // 抢占优先级
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;        // 响应优先级
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStruct);

    /////////////////////
    /*配置TXEN引脚(NRF流控制) PA0 */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    memset(&GPIO_InitStruct, 0, sizeof(GPIO_InitStruct));
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOA, &GPIO_InitStruct);
    // pa0外部中断
    EXTI_InitTypeDef EXTI_InitStructure;
    EXTI_InitStructure.EXTI_Line = EXTI_Line0;                     // 线编号
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;            // 中断
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; // 上升沿下降沿
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);
    EXTI_ClearITPendingBit(EXTI_Line0); // 线编号
    NVIC_EnableIRQ(EXTI0_IRQn);         // 外部中断使能
}

void mine_usart2_send(int ch)
{
    USART_SendData(USART2, (uint8_t)ch);
    while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET)
        ;
}
//
static uint8_t usart2_rx_data[1024] = {0};
static uint16_t usart2_rx_index = 0;

// 接收回调
atkp_t mine_usart2_packet;
void onUsart2Receive(uint8_t *data, uint16_t len)
{
    // atkp_t packet = mine_usart2_packet;
    //  static MiniFlyMsg_t msg;
    //|0 |AF|msgID|dataLen|data[0]|data[1]|data[2]|
    //|AA|AF|msgID|dataLen|data[0]|data[1]|data[2]|
    //|AA|AF|msgID|dataLen|data[0]|data[1]|data[2]|
    if (len >= 7)
    {

        if (data[0] == 0xAA && data[1] == 0XAF && data[2] == DOWN_REMOTER && data[4] == REMOTER_CMD && data[5] == CMD_FLIGHT_LAND)
        {

            // packet.msgID = data[2];
            // packet.dataLen = data[3];
            // memcpy(packet.data, data + 4, packet.dataLen);

            // //
            // printf("usart2 receive:");
            // for (size_t i = 0; i < len; i++)
            // {
            //     printf(" %02x ", data[i]);
            // }
            // printf("\n");

            // // printfPacket(&packet);
            // mine_remote_add_queue(&packet);
            mine_fly_control_set_fly_state(data[6]);
        }
    }
    // printf("\n\t");
    // for (int i = 0; i < len; i++)
    // {
    //     printf(" %02x ", data[i]);
    // }
    // printf("\n串口2收到 : %s,%d \n", data, len);
}

// 清空缓存数据
void clearUsart2RxBuf()
{
    usart2_rx_index = 0;
    memset(usart2_rx_data, 0, sizeof(usart2_rx_data));
}
/**
 * 串口回调
 */
void USART2_IRQHandler(void)
{
    // 接收
    if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
    {                                             // 接收中断
        uint8_t data = USART_ReceiveData(USART2); // 读取数据
        // 处理数据（如存入缓冲区）
        USART_ClearITPendingBit(USART2, USART_IT_RXNE); // 清除标志
                                                        // 读取数据
        usart2_rx_data[usart2_rx_index] = data;
        usart2_rx_index++;
    }

    if (USART_GetITStatus(USART2, USART_IT_IDLE) != RESET)
    {
        USART_ClearITPendingBit(USART2, USART_IT_IDLE);
        uint8_t data = USART_ReceiveData(USART2);
        usart2_rx_data[usart2_rx_index] = '\0';
        // 回调
        onUsart2Receive(usart2_rx_data, usart2_rx_index);
        //
        clearUsart2RxBuf();
    }
}

/**
 *
 * 中断回调
 *
 * */
void __attribute__((used)) EXTI0_Callback(void)
{
    EXTI_ClearFlag(EXTI_Line0); // 清空
    if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == Bit_SET)
    {
        USART_ClearITPendingBit(USART2, USART_IT_RXNE); // 清除标志
        // printf("usart2无线外部中断:1\n");//printf打印会抢占飞机起降的优先级,导致接不能根据命令做出反应
        //  uartslkPauseDma();
        //   ledSet(LED_GREEN_R, 1);
    }
    else
    {
        // USART_ClearITPendingBit(USART2, USART_IT_TC);
        USART_ClearFlag(USART2, USART_FLAG_TC); /* 清除传输完成中断标志位 */
        // printf("usart2无线外部中断:0\n");//printf打印会抢占飞机起降的优先级,导致接不能根据命令做出反应
        //  uartslkResumeDma();
        //   ledSet(LED_GREEN_R, 0);
    }
}
